// Copyright 2017 uSwitch
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package metadata

import (
	"net/http"
	"time"

	log "github.com/sirupsen/logrus"
)

type statusWriter struct {
	http.ResponseWriter
	statusCode int
}

func newStatusWriter(w http.ResponseWriter) *statusWriter {
	return &statusWriter{w, http.StatusOK}
}

func (s *statusWriter) WriteHeader(code int) {
	s.statusCode = code
	s.ResponseWriter.WriteHeader(code)
}

func requestFields(req *http.Request) log.Fields {
	return log.Fields{
		"method": req.Method,
		"path":   req.URL.Path,
		"addr":   req.RemoteAddr,
	}
}

func loggingHandler(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		requestTimer := time.Now()
		statusWriter := newStatusWriter(w)
		handler.ServeHTTP(statusWriter, req)
		fields := log.Fields{
			"headers":  w.Header(),
			"status":   statusWriter.statusCode,
			"duration": float64(time.Since(requestTimer) / time.Millisecond),
		}
		logger := log.WithFields(requestFields(req)).WithFields(fields)
		if statusWriter.statusCode < 400 {
			logger.Debug("processed request")
		} else {
			logger.Info("processed request")
		}
	})
}
